#include <iostream>
#include<cassert>
using namespace std;

namespace aoqiang
{
    //不计算 \0 
    size_t strlen(const char *str)
    {
        assert(str);
        size_t count = 0;
        while(*str != '\0')
        {
            count++;
            str++;
        }   
        return count;
    }
    //将s2指向的内容 复制的s1指向的空间,返回s1的空间
    char* strcpy(char* dest,const char* src)
    {
        char* tmp = dest;
        assert(src);

        while(*src != '\0')
        {
            *dest = *src;
            dest++;
            src++;
        }
        return tmp;
    }
    char* strcat(char* s1 ,const char* s2)
    {
        char* tmp = s1;
        //找到s1的末尾处
        while(*s1)
        {
            s1++;
        }
        while (*s2 != '\0')
        {
            *s1 = *s2;
            s1++;
            s2++;
        }
        *s1 = '\0';
        return tmp;
    }

    int strcmp(const char* s1,const char* s2)
    {
        assert(s1);
        assert(s2);
        while(*s1 && *s2)
        {
            if(*s1 > *s2)
            {
                return 1;
            }
            else if(*s1 < *s2)
            {
                return -1;
            }
            s1++;
            s2++;
        }
        // 循环结束后，如果两个字符串不等，返回非零值
        // 如果s1和s2在相同位置结束，返回0
        return *s1 - *s2;
    }

    int strncmp(const char*s1,const char*s2,size_t n)
    {
        assert(s1);
        assert(s2);
        // assert(n > 0);
        if(n == 0)
        {
            return 0;
        }
        while(*s1 && *s2 && n > 0)
        {
            if(*s1 > *s2)
            {
                return 1;
            }
            else if(*s1 < *s2)
            {
                return -1;
            }
            s1++;
            s2++;
            n--;
        }
        //到这里有可能是字符串结束了
        if(n == 0)
        {
            return 0;
        }
        if(*s1)
        {
            return 1;
        }
        return -1;
    }

    void* memcpy(void* dest,void* src,size_t num)
    {
        void* ret = dest;

        assert(dest && src);
        while(num--)
        {
            *(char*)dest = *(char*)src;
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
        return ret;
    }
    //和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
    // 如果源空间和目标空间出现重叠，就得使用memmove函数处理。
    void* memmove(void* dest,void* src,size_t num)
    {
        void* ret = dest;
        assert(dest && src);
        //前-后
        if(dest < src)
        {
            while(num--)
            {
                *(char*)dest = *(char*)src;
                dest = (char*)dest + 1;
                src = (char*)src + 1;
            }
        }
        else
        {
            //后到前
            while(num--)
            {
                *((char*)dest + num) = *((char*)src + num);
            }   
        }
        return ret;
    }
}

